/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.testis.orm.dynamicmap.validation;

import java.util.HashMap;
import java.util.LinkedList;

import org.testis.orm.refinedclasses.DynamicMapDesignTreeNode;
import org.testis.orm.refinedclasses.DynamicMapObject;
import org.testis.orm.refinedclasses.DynamicMapParameter;

/**
 * 
 * @author nurhat
 */
public abstract class IValidateDynamicMapNode {

    private HashMap<String, String> m_postFixOFAbstractIds = new HashMap<String, String>();

    public IValidateDynamicMapNode() {
	m_postFixOFAbstractIds.put("UIPage", "_page");
	m_postFixOFAbstractIds.put("UIFrame", "_frame");
	m_postFixOFAbstractIds.put("UILink", "_lnk");
	m_postFixOFAbstractIds.put("UIMultiSelectListBox", "_select");
	m_postFixOFAbstractIds.put("UITextBox", "_txt");
	m_postFixOFAbstractIds.put("UIButton", "_btn");
	m_postFixOFAbstractIds.put("UICheckBox", "_cb");
	m_postFixOFAbstractIds.put("UIWindow", "_win");
	m_postFixOFAbstractIds.put("UILabel", "_lbl");
	m_postFixOFAbstractIds.put("UIFileSelector", "_file");
	m_postFixOFAbstractIds.put("UIDynamicGrid", "_dyn");
	m_postFixOFAbstractIds.put("UIDropDown", "_cmb");
	m_postFixOFAbstractIds.put("UIOption", "_opt");
	m_postFixOFAbstractIds.put("UIRadioButton", "_rb");
	m_postFixOFAbstractIds.put("UIRadioButtonGroup", "_rbg");
	m_postFixOFAbstractIds.put("UICheckBoxGroup", "_cbg");
	m_postFixOFAbstractIds.put("UITextArea", "_txtarea");
    }

    abstract public void validate(DynamicMapDesignTreeNode node,
	    DynamicMapDesignTreeNode root);

    public String getParameterValue(String paramName,
	    DynamicMapDesignTreeNode node) {
	DynamicMapObject object = node.getObject();
	DynamicMapParameter parameter = object.getParameterByName(paramName);
	if (parameter != null) {
	    return parameter.getValue();
	}
	return null;
    }

    private DynamicMapParameter getParameterByName(String paramName,
	    DynamicMapDesignTreeNode node) {
	DynamicMapObject object = node.getObject();
	DynamicMapParameter parameter = object.getParameterByName(paramName);
	return parameter;
    }

    public void validateParameter(String paramName,
	    DynamicMapDesignTreeNode node, DynamicMapDesignTreeNode root,
	    String targetObjectType, boolean failsIfEmpty) {
	DynamicMapObject object = node.getObject();
	DynamicMapParameter parameter = object.getParameterByName(paramName);
	if (parameter != null) {
	    String parValue = parameter.getValue();
	    if (!parValue.equals("")) {
		if (!targetObjectType.equals("")) {
		    DynamicMapDesignTreeNode targetObj = root
			    .searchObjectByParameterValue("AbstractId",
				    parValue, targetObjectType);
		    if (targetObj == null) {
			node.appendValidationError("Given " + paramName
				+ " is invalid. " + targetObjectType
				+ " not found");
		    }
		} else if (targetObjectType.equals("*")) {
		    DynamicMapDesignTreeNode targetObj = root.searchObject(
			    "AbstractId", parValue);
		    if (targetObj == null) {
			node.appendValidationError("Given " + paramName
				+ " is invalid. " + targetObjectType
				+ " not found");
		    }
		}
	    } else if (failsIfEmpty) {
		node.appendValidationError("Given " + paramName
			+ " is invalid.It is empty...");
	    }
	} else if (failsIfEmpty) {
	    node.appendValidationError(paramName
		    + " parameter is  not found...");
	}
    }

    public void validateParameter(String paramName,
	    DynamicMapDesignTreeNode node, String verifyValue,
	    boolean failsIfNotExists) {
	DynamicMapObject object = node.getObject();
	DynamicMapParameter parameter = object.getParameterByName(paramName);
	if (parameter != null) {
	    String parValue = parameter.getValue();
	    if (!parValue.equals(verifyValue)) {
		node.appendValidationError("Given " + paramName
			+ " is invalid.It must be " + verifyValue + "...");
	    }
	} else if (failsIfNotExists) {
	    node.appendValidationError(paramName
		    + " parameter is  not found...");
	}
    }

    public void validateAbstractIdPostFix(DynamicMapDesignTreeNode node) {
	DynamicMapObject object = node.getObject();
	DynamicMapParameter parameter = object.getParameterByName("AbstractId");

	if (parameter != null) {
	    String postFix = m_postFixOFAbstractIds.get(object.getTypeName());
	    if (postFix != null && !parameter.getValue().equals("")) {
		if (!parameter.getValue().endsWith(postFix)) {
		    node.appendValidationError("Abstract Id parameter must end with following value:"
			    + postFix);
		}
	    }
	}
    }

    public void validateParameterValueUniqueness(DynamicMapDesignTreeNode node,
	    DynamicMapDesignTreeNode root, String paramName) {
	if (getParameterByName(paramName, node) == null) {
	    return;
	}
	String value = getParameterValue(paramName, node);
	if (value.equals("")) {
	    return;
	}
	LinkedList<DynamicMapDesignTreeNode> output = new LinkedList<DynamicMapDesignTreeNode>();
	root.searchObjects(paramName, value, output);
	if (output.size() > 1) {
	    StringBuilder err = new StringBuilder();
	    err.append("Following node also has same value for parameter:"
		    + paramName);
	    for (int i = 0; i < output.size(); i++) {
		if (output.get(i) != node) {
		    err.append("\r\nNode Name:" + output.get(i).getName());
		    if (output.get(i).getParent() != null) {
			err.append("\n\tNode Parent Name:"
				+ output.get(i).getParent());
			if (getParameterByName("AbstractId", output.get(i)
				.getParent()) != null) {
			    err.append("\n\tNode Parent AbstractId:"
				    + getParameterValue(paramName, output
					    .get(i).getParent()));
			}
		    }
		}
	    }
	}
    }
}
